<template>
  <view class="markdown-content">
    <rich-text :nodes="renderedContent"></rich-text>
  </view>
</template>

<script>
import MarkdownIt from 'markdown-it';
import markdownItTaskLists from 'markdown-it-task-lists';
import Prism from 'prismjs';

// 导入Prism.js语言支持
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-markup';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-java';
import 'prismjs/components/prism-c';
import 'prismjs/components/prism-cpp';
import 'prismjs/components/prism-csharp';
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-json';
import 'prismjs/components/prism-markdown';
import 'prismjs/components/prism-sql';

export default {
  name: 'MarkdownRenderer',
  props: {
    content: {
      type: String,
      required: true,
      default: ''
    },
    darkMode: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      md: null,
      renderedContent: ''
    };
  },
  watch: {
    content: {
      immediate: true,
      handler(newContent) {
        // 直接渲染内容，不做额外处理
        this.renderMarkdown(newContent);
      }
    },
    darkMode() {
      // 当暗黑模式切换时重新渲染内容
      this.renderMarkdown(this.content);
    }
  },
  mounted() {
    this.initMarkdownIt();
    this.renderMarkdown(this.content);
    
    // 添加代码块复制事件监听器
    document.addEventListener('copyCode', (e) => {
      if (e.detail) {
        this.copyCodeBlock(e.detail);
      }
    });
  },
  beforeDestroy() {
    // 移除事件监听器
    document.removeEventListener('copyCode', this.copyCodeBlock);
  },
  methods: {
    initMarkdownIt() {
      // 创建markdown-it实例并配置
      this.md = new MarkdownIt({
        html: true,
        breaks: true,
        linkify: true,
        typographer: true, // 启用排版增强
        highlight: (str, lang) => {
          if (lang && Prism.languages[lang]) {
            try {
              // 使用Prism.js进行代码高亮
              return '<pre class="language-' + lang + '"><code class="language-' + lang + '">' +
                Prism.highlight(str, Prism.languages[lang], lang) +
                '</code></pre>';
            } catch (e) {
              console.error('Prism高亮处理错误:', e);
            }
          }

          // 使用普通代码块
          return '<pre class="language-plaintext"><code>' +
            this.md.utils.escapeHtml(str) +
            '</code></pre>';
        }
      });

      // 使用插件
      this.md.use(markdownItTaskLists);

      // 自定义标题的渲染方式
      this.md.renderer.rules.heading_open = (tokens, idx, options, env, slf) => {
        const token = tokens[idx];
        const level = token.tag.slice(1); // 获取标题级别
        return `<${token.tag} class="md-heading md-h${level}">`;
      };

      // 增强对行内代码的渲染
      this.md.renderer.rules.code_inline = (tokens, idx, options, env, slf) => {
        const token = tokens[idx];
        return '<code class="md-code-inline">' + this.md.utils.escapeHtml(token.content) + '</code>';
      };
    },
    
    renderMarkdown(content) {
      if (!content) {
        this.renderedContent = '';
        return;
      }

      try {
        // 预处理内容，自动将裸链接转为markdown链接
        let processedContent = content.replace(/(https?:\/\/[^\s]+)/g, '[$1]($1)');
        
        // 确保#号后有空格，这是Markdown标准
        processedContent = processedContent.replace(/^(#+)([^\s#])/gm, '$1 $2');
        
        // 预处理内容中的英文单词间空格，确保在markdown解析前就处理好空格问题
        // 将连续的英文字母和数字视为单词，确保单词间有空格
        processedContent = processedContent.replace(/([a-zA-Z0-9]+)(\s)([a-zA-Z0-9]+)/g, function(match, p1, p2, p3) {
          // 使用更多空格替换原空格，确保渲染后依然可见
          return p1 + ' ' + p3;
        });
        
        // 使用markdown-it解析Markdown
        let formatted = this.md.render(processedContent);

        // 确保所有内容都被包裹在div中，以便正确显示
        if (!formatted.startsWith('<div>')) {
          formatted = '<div>' + formatted + '</div>';
        }
        
        // 对解析后的HTML进行空格处理，将所有空格转换为HTML空格实体
        formatted = formatted.replace(/>([^<]+)</g, function(match, text) {
          // 只处理文本内容部分，保留HTML标签
          const processedText = text.replace(/(\s)/g, ' ');
          return '>' + processedText + '<';
        });

        // 为所有代码块添加复制按钮
        formatted = formatted.replace(/<pre\s+class="language-([^"]+)">/g,
          '<div class="code-block-wrapper"><div class="code-block-header"><span class="code-language">$1</span>' +
          '<span class="copy-code-btn" onclick="document.dispatchEvent(new CustomEvent(\'copyCode\', {detail: event}))">复制代码</span></div>' +
          '<pre class="language-$1">');

        // 闭合代码块包装器
        formatted = formatted.replace(/<\/pre>/g, '</pre></div>');

        // 为标题添加特殊样式
        formatted = formatted.replace(/<h(\d)[^>]*>(.*?)<\/h\1>/g, 
          (match, level, content) => {
            return `<div class="md-heading-container"><h${level} class="md-heading md-h${level}">${content}</h${level}></div>`;
          }
        );

        // 应用暗黑模式类
        if (this.darkMode) {
          formatted = formatted.replace(/<div>/g, '<div class="dark-mode">');
        }

        this.renderedContent = formatted;
      } catch (error) {
        console.error('解析Markdown时出错:', error);

        // 简化错误处理逻辑，保持基本格式
        let formatted = content;
        
        // 简单处理标题
        formatted = formatted.replace(/^(#+)\s+(.*?)$/gm, (match, hashes, text) => {
          const level = Math.min(hashes.length, 6); // 最大支持h6
          return `<h${level} class="md-heading md-h${level}">${text}</h${level}>`;
        });
        
        // 替换换行符
        formatted = formatted.replace(/\n/g, '<br>');
        
        // 基本HTML转义
        formatted = formatted
          .replace(/&/g, '&amp;')
          .replace(/</g, '&lt;')
          .replace(/>/g, '&gt;')
          .replace(/"/g, '&quot;')
          .replace(/'/g, '&#039;');
          
        // 处理空格
        formatted = formatted.replace(/(\s)/g, ' ');

        this.renderedContent = '<div>' + formatted + '</div>';
      }
    },
    
    copyCodeBlock(event) {
      // 获取代码文本
      const codeBlock = event.target.closest('.code-block-wrapper');
      if (!codeBlock) return;
      
      const preElement = codeBlock.querySelector('pre');
      if (!preElement) return;
      
      const codeElement = preElement.querySelector('code');
      if (!codeElement) return;
      
      // 获取代码文本内容
      const codeText = codeElement.textContent || '';
      
      // 更新复制按钮状态
      const copyBtn = event.target;
      if (copyBtn) {
        copyBtn.textContent = '复制成功';
        copyBtn.classList.add('copy-success');
        
        // 2秒后恢复按钮文本
        setTimeout(() => {
          copyBtn.textContent = '复制代码';
          copyBtn.classList.remove('copy-success');
        }, 2000);
      }
      
      // 复制到剪贴板
      uni.setClipboardData({
        data: codeText,
        success: () => {
          uni.showToast({
            title: '代码已复制',
            icon: 'success',
            duration: 2000
          });
        }
      });
    }
  }
};
</script>

<style>
.markdown-content {
  width: 100%;
}

/* 为解决空格问题，添加额外的空格处理样式 */
.markdown-content :deep(p),
.markdown-content :deep(li),
.markdown-content :deep(blockquote) {
  white-space: pre-wrap !important;
  word-break: break-word !important;
  word-spacing: 0.25em !important; /* 确保单词之间有足够的间距 */
}

/* 段落样式优化 */
.markdown-content :deep(p) {
  white-space: pre-wrap;
  word-break: break-word;
  margin: 0 0 12rpx 0;
  padding: 0;
  line-height: 1.7;
}

/* 最后一个段落不需要底部边距 */
.markdown-content :deep(p:last-child) {
  margin-bottom: 0;
}

/* 标题样式增强 */
.markdown-content :deep(.md-heading-container) {
  width: 100%;
  margin: 24rpx 0 16rpx 0;
}

.markdown-content :deep(.md-heading) {
  font-weight: bold;
  line-height: 1.4;
  position: relative;
  padding-bottom: 8rpx;
  width: 100%;
  display: block;
}

.markdown-content :deep(.md-h1) {
  font-size: 24px;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 12rpx;
  margin-bottom: 16rpx;
}

.markdown-content :deep(.md-h2) {
  font-size: 20px;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 10rpx;
  margin-bottom: 14rpx;
}

.markdown-content :deep(.md-h3) {
  font-size: 18px;
}

.markdown-content :deep(.md-h4) {
  font-size: 16px;
}

.markdown-content :deep(.md-h5),
.markdown-content :deep(.md-h6) {
  font-size: 14px;
}

/* 列表样式优化 */
.markdown-content :deep(ul),
.markdown-content :deep(ol) {
  padding-left: 40rpx;
  margin: 16rpx 0;
}

.markdown-content :deep(li) {
  margin: 8rpx 0;
  padding-left: 6rpx;
}

/* 嵌套列表样式 */
.markdown-content :deep(li ul),
.markdown-content :deep(li ol) {
  margin: 8rpx 0;
}

/* 引用块样式 */
.markdown-content :deep(blockquote) {
  border-left: 4px solid #c8c8c8;
  padding: 12rpx 20rpx;
  color: #555;
  margin: 16rpx 0;
  background-color: #f5f5f5;
  border-radius: 0 4rpx 4rpx 0;
  font-style: italic;
}

/* 水平线样式 */
.markdown-content :deep(hr) {
  border: none;
  border-top: 1px solid #ddd;
  margin: 20rpx 0;
}

/* 表格样式 */
.markdown-content :deep(table) {
  border-collapse: collapse;
  width: 100%;
  margin: 16rpx 0;
  overflow-x: auto;
  display: block;
}

.markdown-content :deep(th),
.markdown-content :deep(td) {
  border: 1px solid #e0e0e0;
  padding: 12rpx 16rpx;
  text-align: left;
  font-size: 14px;
}

.markdown-content :deep(th) {
  background-color: #f5f5f5;
  font-weight: bold;
}

.markdown-content :deep(tr:nth-child(even)) {
  background-color: #fafafa;
}

/* 图片样式优化 */
.markdown-content :deep(img) {
  max-width: 100%;
  height: auto;
  border-radius: 8rpx;
  margin: 16rpx 0;
  display: block;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 链接样式优化 */
.markdown-content :deep(a) {
  color: #2979ff;
  text-decoration: none;
  border-bottom: 1px solid #2979ff;
  padding-bottom: 2rpx;
  transition: all 0.2s ease;
}

/* 代码块包装器样式 */
.markdown-content :deep(.code-block-wrapper) {
  position: relative;
  margin: 20rpx 0;
  border-radius: 10rpx;
  border: 1px solid #e0e0e0;
  background-color: #fafafa;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

/* 代码块容器样式 */
.markdown-content :deep(.code-block-wrapper pre) {
  margin: 0;
  border-radius: 0;
  overflow-x: auto;
  background-color: #fafafa;
  border: none;
  white-space: pre;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
  /* 确保水平滚动 */
  word-wrap: normal;
  word-break: keep-all;
  overflow-wrap: normal;
  padding: 20rpx;
  padding-top: 60rpx;
  /* 为头部留出空间 */
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.5;
}

/* 代码块头部样式 */
.markdown-content :deep(.code-block-header) {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10rpx 20rpx;
  background-color: #f0f0f0;
  border-bottom: 1px solid #e0e0e0;
  font-size: 12px;
  color: #555;
  position: absolute;
  /* 使头部固定 */
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  height: 40rpx;
  line-height: 40rpx;
  width: 100%;
  box-sizing: border-box;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.markdown-content :deep(.code-language) {
  text-transform: uppercase;
  font-weight: bold;
  font-size: 12px;
  color: #444;
  letter-spacing: 0.5px;
}

.markdown-content :deep(.copy-code-btn) {
  cursor: pointer;
  padding: 4rpx 14rpx;
  border-radius: 4rpx;
  background-color: #e0e0e0;
  transition: all 0.2s ease;
  font-size: 12px;
  color: #333;
  font-weight: 500;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  height: 30rpx;
  line-height: 30rpx;
  position: relative;
  /* 确保在滚动时保持可见 */
  z-index: 11;
  /* 确保在代码上方 */
  margin-left: 10rpx;
}

.markdown-content :deep(.copy-code-btn.copy-success) {
  background-color: rgba(76, 175, 80, 0.8);
  color: white;
}

.markdown-content :deep(.copy-code-btn:hover) {
  background-color: #d0d0d0;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transform: translateY(-1px);
}

.markdown-content :deep(.copy-code-btn:active) {
  transform: translateY(1px);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
}

/* 内联代码样式 */
.markdown-content :deep(.md-code-inline) {
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 3px;
  padding: 2px 4px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 0.9em;
}

/* 暗黑模式样式 */
.markdown-content :deep(.dark-mode) {
  color: #e0e0e0;
}

.markdown-content :deep(.dark-mode .md-heading) {
  color: #ffffff;
}

.markdown-content :deep(.dark-mode .md-h1),
.markdown-content :deep(.dark-mode .md-h2) {
  border-bottom-color: #444;
}

.markdown-content :deep(.dark-mode blockquote) {
  background-color: #2c2c2c;
  border-left-color: #555;
  color: #cccccc;
}

.markdown-content :deep(.dark-mode a) {
  color: #64b5f6;
  border-bottom-color: #64b5f6;
}

.markdown-content :deep(.dark-mode .md-code-inline) {
  background-color: rgba(255, 255, 255, 0.1);
  color: #e0e0e0;
}

.markdown-content :deep(.dark-mode .code-block-wrapper) {
  background-color: #2c2c2c;
  border-color: #444;
}

.markdown-content :deep(.dark-mode .code-block-header) {
  background-color: #333;
  border-bottom-color: #444;
  color: #e0e0e0;
}

.markdown-content :deep(.dark-mode .code-block-wrapper pre) {
  background-color: #2c2c2c;
  color: #e0e0e0;
}

.markdown-content :deep(.dark-mode table) {
  border-color: #444;
}

.markdown-content :deep(.dark-mode th),
.markdown-content :deep(.dark-mode td) {
  border-color: #444;
}

.markdown-content :deep(.dark-mode th) {
  background-color: #333;
}

.markdown-content :deep(.dark-mode tr:nth-child(even)) {
  background-color: #2a2a2a;
}
</style>
